package sh.grapendaal.tsuushin.module.uno.engine.service.impl;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import sh.grapendaal.tsuushin.module.uno.engine.UnoException;
import sh.grapendaal.tsuushin.module.uno.engine.domain.Player;
import sh.grapendaal.tsuushin.module.uno.engine.domain.achievement.Achievement;
import sh.grapendaal.tsuushin.module.uno.engine.event.GameEvent;
import sh.grapendaal.tsuushin.module.uno.engine.service.PlayerService;

import com.google.common.collect.Iterators;
import com.google.common.collect.PeekingIterator;

public class PlayerServiceImpl implements PlayerService {

	private List<Player> players = new LinkedList<Player>();
	private PeekingIterator<Player> playerIterator;
	private Player currentPlayer;
	
	@Override
	public void initialize() {
		Collections.shuffle(this.players);
		this.currentPlayer = nextPlayer();
	}

	@Override
	public int getNumPlayers() {
		return this.players.size();
	}

	@Override
	public List<Player> getPlayers() {
		return this.players;
	}
	
	@Override
	public boolean addPlayer(Player player) {
		if (!this.players.contains(player)) {
			return this.players.add(player);			
		}
		return false;
	}

	@Override
	public boolean removePlayer(Player player) {
		if (this.players.contains(player)) {
			return this.players.remove(player);
		}
		return false;
	}

	@Override
	public boolean hasPlayer(Player player) {
		return players.contains(player);
	}

	@Override
	public Player getPlayerByNickname(String nickname) {
		for (Player otherPlayer : this.players) {
			if (otherPlayer.getNickname().equals(nickname)) {
				return otherPlayer;
			}
		}
		throw new UnoException("Player \"" + nickname + "\" not found.");
	}
	
	@Override
	public Player getCurrentPlayer() {
		return this.currentPlayer;
	}
	
	@Override
	public Player nextPlayer() {
		if (this.playerIterator == null) {
			this.playerIterator = Iterators.peekingIterator(Iterators.cycle(this.players));
		}
		
		this.currentPlayer = this.playerIterator.next();
		return this.currentPlayer;
	}

	@Override
	public Player peekNextPlayer() {
		return this.playerIterator.peek();
	}
	
	@Override
	public void reverseRotation() {
		Collections.reverse(this.players);
		this.playerIterator = null;
	}

	@Override
	public void onPlayerJoin(GameEvent event) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onPlayerLeave(GameEvent event) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onGameStart(GameEvent event) {
		
	}

	@Override
	public void onGameStop(GameEvent event) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onCardPlay(GameEvent event) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onCardDraw(GameEvent event) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onCardPass(GameEvent event) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onGameEnd(GameEvent event) {
//		for (Player player : this.players) {
//			player.onGameEnd(event);
//		}
	}

	@Override
	public void onTurnStart(GameEvent event) {
		getPlayerByNickname(event.getGameState().getCurrentPlayer().getNickname()).startTurn();
	}

	@Override
	public void onTurnSkip(GameEvent event) {
//		event.getPlayer().onTurnSkip(event);
	}

	@Override
	public void onTurnEnd(GameEvent event) {
		getPlayerByNickname(event.getGameState().getCurrentPlayer().getNickname()).endTurn();
	}

	@Override
	public void onAchievementUnlock(GameEvent event, Achievement achievement) {
		getPlayerByNickname(event.getGameState().getCurrentPlayer().getNickname()).unlockAchievement(achievement);
	}
}
